{% extends "../page.html" %}

{% block head %}
<style type="text/css">
    i.layui-icon,
    i.yunj-icon {
        font-size: 14px !important;
    }

    .ztree {
        margin-top: 15px !important;
        padding: 15px !important;
        min-height: 300px;
        background: #fff;
        border-top: 1px solid #e6e6e6;
    }

    .ztree span[treenode_ico] {
        margin: 2px !important;
        height: 17px !important;
        background-size: cover !important;
        background-position: center !important;
    }
</style>
{% endblock %}

{% block content %}
<div class="layui-row">
    <div class="layui-col-md6">
        <div class="layui-card normal-box" data-args='{{ data.normal|tojson|safe }}'>
            <div class="layui-card-body">
                <div class="layui-tab layui-tab-brief">
                    <ul class="layui-tab-title">
                        <li data-state="11" class="layui-this">正常(<span class="count">0</span>)</li>
                    </ul>
                </div>
            </div>
            <div class="layui-card-body" style="padding-top: 0">
                {% if data.normal.HasAddAuth %}
                <button type="button" class="layui-btn layui-btn-sm" id="btn_top_category_add">
                    <i class="layui-icon layui-icon-add-circle-fine"></i> 新增顶级分类
                </button>
                {% endif %}
                <ul class="ztree" id="normal_category_tree"></ul>
            </div>
        </div>
    </div>
    {% if data.normal.HasRecycleBinListAuth %}
    <div class="layui-col-md6">
        <table type="yunj" id="CategoryRecyleBinList"></table>
    </div>
    {% endif %}
</div>
{% endblock %}

{% block script %}
<script type="text/javascript">
    layui.use(['yunj', "jquery"], function () {
        let win = window;
        let doc = document;
        let $ = layui.jquery;

        let event = {
            add: {
                "type": "Add",
                "title": "添加"
            },
            recycleBin: {
                "type": "RecycleBin",
                "title": "移入回收站"
            },
            drag: {
                "type": "Drag",
                "title": "排序"
            }
        };

        class CategoryNormal {

            constructor() {

                this.args = {};

                this.boxEl = null;
                this.stateCountEl = null;
                this.btnTopCategoryAdd = null;
                this.nodes = [];

                this.ztree = null;
                this.ztreeCanDrag = true;

                this.init().catch(e => {
                    console.log(e)
                });
            }

            async init() {
                let that = this;
                that.initEl();
                await that.ztreeRender();
                that.setEventBind();
                return "done";
            }

            initEl() {
                let that = this;
                let boxEl = $(".normal-box");
                that.boxEl = boxEl;
                that.args = boxEl.data("args");
                that.stateCountEl = boxEl.find(".layui-tab ul .count");
                that.btnTopCategoryAdd = boxEl.find("#btn_top_category_add");
            }

            async ztreeRender() {
                let that = this;
                let nodes = await that.requestNodes();
                that.handleNodes(nodes);
                await that.initZtreeResource();
                that.initTree();
                return "done";
            }

            requestNodes() {
                let that = this;
                return new Promise((resolve, reject) => {
                    yunj.request(that.args.treeNodesUrl).then(res => {
                        resolve(res.data.nodes);
                    }).catch(e => {
                        reject("分类节点请求失败");
                    });
                });
            }

            handleNodes(nodes) {
                let that = this;
                let nodeMap = new Map();
                let l = nodes.length;
                for (let i = 0; i < l; i++) {
                    // id string
                    nodes[i].id = nodes[i].id.toString();
                    let node = nodes[i];
                    let id = node.id;
                    nodeMap.set(id, i);
                    // icon
                    nodes[i].icon = node.img.length ? node.img : yunj.defaultImageUrl();
                    // 展开
                    nodes[i].open = true;
                    // 是否可选
                    let nocheck = false;
                    for (let j = 0; j < l; j++) {
                        if (id !== nodes[j].pid.toString()) continue;
                        nocheck = true;
                        break;
                    }
                    nodes[i].nocheck = nocheck;
                }
                that.nodes = nodes;
                that.stateCountEl.html(nodes.length);
            }

            async initZtreeResource() {
                let that = this;
                win.jQuery = $;
                await yunj.includeCss('/yunj/static/yunj/libs/zTree_v3/css/metroStyle/metroStyle.css');
                await yunj.includeJs('/yunj/static/yunj/libs/zTree_v3/js/jquery.ztree.core.js');
                await yunj.includeJs('/yunj/static/yunj/libs/zTree_v3/js/jquery.ztree.excheck.js');
                await yunj.includeJs('/yunj/static/yunj/libs/zTree_v3/js/jquery.ztree.exedit.js');
                return "done";
            }

            initTree() {
                let that = this;

                let setting = {
                    edit: {
                        enable: true,
                        showRemoveBtn: false,
                        showRenameBtn: false,
                    },
                    view: {
                        showIcon: true,
                        selectedMulti: false,
                        addHoverDom: function (treeId, treeNode) {
                            that.ztreeAddHoverDom(treeId, treeNode);
                        },
                        removeHoverDom: function (treeId, treeNode) {
                            $(`#${treeNode.tId}_action_box`).remove();
                        },
                    },
                    data: {
                        simpleData: {
                            enable: true,
                            pIdKey: "pid",
                        }
                    }
                };
                if (that.args.hasSortAuth) {
                    setting.callback = {
                        beforeDrag: function (treeId, treeNodes) {
                            return that.ztreeBeforeDrag(treeId, treeNodes);
                        },
                        beforeDrop: function (treeId, treeNodes, targetNode, moveType) {
                            return that.ztreeBeforeDrop(treeId, treeNodes);
                        },
                        onDrop: function (event, treeId, treeNodes, targetNode, moveType) {
                            that.ztreeOnDrop(event, treeId, treeNodes, targetNode, moveType)
                        }
                    }
                }

                $.fn.zTree.init($('#normal_category_tree'), setting, that.nodes);

                that.ztree = $.fn.zTree.getZTreeObj("normal_category_tree");
                that.ztree.setting.edit.drag.isCopy = false;
                that.ztree.setting.edit.drag.isMove = that.args.hasSortAuth;
                that.ztree.setting.edit.drag.prev = that.args.hasSortAuth;
                that.ztree.setting.edit.drag.inner = that.args.hasSortAuth;
                that.ztree.setting.edit.drag.next = that.args.hasSortAuth;
            }

            recycleBinTable() {
                let that = this;
                return yunj.table["CategoryRecyleBinList"];
            }

            setEventBind() {
                let that = this;

                that.btnTopCategoryAdd.on('click', function (e) {
                    let el = $(this);
                    if (el.prop('disabled')) return;
                    let elHtml = el.html();
                    el.attr('disabled', true);
                    el.html('loading...');
                    that.categoryAdd().then(res => {
                        el.attr('disabled', false);
                        el.html(elHtml);
                    });
                    e.stopPropagation();
                });

                that.boxEl.on("click", ".ztree span[treenode_ico]", function (e) {
                    let src = $(this).css("backgroundImage").replace("url(\"", "").replace("\")", "");
                    yunj.previewImg(src);
                    e.stopPropagation();
                });

                // 监听回收站数据触发恢复正常事件
                $(doc).bind("yunj_table_CategoryRecyleBinList_event_normal_done", function (e, requestData, responseRes) {
                    that.ztreeRender().catch(e => {
                        console.log(e);
                    });
                });

            }

            ztreeAddHoverDom(treeId, treeNode) {
                let that = this;

                let treeNodeID = treeNode.tId;
                let nodeEl = $(`#${treeNodeID}_span`);
                if ($(`#${treeNodeID}_action_box`).length > 0 || treeNode.alias == that.args.defaultAlias) return;
                let domContent = '';
                if (that.args.hasAddAuth && (treeNode.level < that.args.levelLimit)) domContent += `<span class="button add" id="${treeNodeID}_add" title="新增"></span>`;
                if (that.args.hasEditAuth) domContent += `<span class="button edit" id="${treeNodeID}_edit" title="编辑"></span>`;
                if (that.args.hasRecycleBinAuth) domContent += `<span class="button remove" id="${treeNodeID}_recycle_bin" title="回收站"></span>`;
                if (!domContent) return;
                domContent = `<span id="${treeNodeID}_action_box">${domContent}</span>`;
                nodeEl.after(domContent);

                let addEl = $(`#${treeNode.tId}_add`);
                if (addEl.length > 0) {
                    addEl.bind("click", function () {
                        that.categoryAdd(treeNode).then();
                    });
                }
                $(`#${treeNode.tId}_edit`).bind("click", function () {
                    yunj.openPopup(yunj.urlPushParam(that.args.editUrl,'id',treeNode.id), "分类编辑", true);
                });
                $(`#${treeNode.tId}_recycle_bin`).bind("click", function () {
                    that.categoryRecycleBin(treeNode);
                });
            }

            ztreeBeforeDrag(treeId, treeNodes) {
                let that = this;
                if (!that.ztreeCanDrag) return false;
                for (let i = 0, l = treeNodes.length; i < l; i++) {
                    if (treeNodes[i].drag === false) return false;
                }
                return true;
            }

            ztreeBeforeDrop(treeId, treeNodes, targetNode, moveType) {
                let that = this;
                return targetNode ? targetNode.drop !== false : true;
            }

            ztreeOnDrop(event, treeId, treeNodes, targetNode, moveType) {
                let that = this;
                // 防止拖拽到目标区域外报错
                if (!targetNode) return;
                if (targetNode.level >= that.args.levelLimit && moveType === "inner") {
                    location.reload();
                    return;
                }
                that.categoryDrag({
                    id: treeNodes[0].id|0,
                    targetId: targetNode.id|0,
                    mode: moveType,
                }).then();
            }

            async categoryDrag(param) {
                let that = this;
                that.ztreeCanDrag = false;
                param.event = "Drag"
                await that.handleEventRequest(param).then(data => {
                    that.ztreeCanDrag = true;
                }).catch(e => {
                    location.reload();
                });
                return 'done';
            }

            async categoryAdd(treeNode = null) {
                let that = this;
                let pid = treeNode === null ? 0 : (treeNode.id | 0);
                await that.handleEventRequest({event:"Add",pid: pid}).then(data => {
                    that.ztree.addNodes(treeNode, {
                        id: data.id,
                        pid: pid,
                        name: data.name,
                        alias: data.alias,
                        icon: data.img || yunj.defaultImageUrl(),
                    });
                    that.stateCount(1);
                });
                return 'done';
            }

            categoryRecycleBin(treeNode) {
                let that = this;
                that.handleEventRequest({event:"RecycleBin",id: (treeNode.id|0)}).then(data => {
                    let count = 1 + that.getTreeNodeChildrenCount(treeNode);
                    that.ztree.removeNode(treeNode);
                    that.stateCount(-count);
                    that.recycleBinTable().render();
                }).catch(e => {
                    yunj.error(e);
                });
            }

            getTreeNodeChildrenCount(treeNode) {
                let that = this;
                let count = 0;
                if (!treeNode.hasOwnProperty("children")) return count;
                treeNode.children.forEach(itemNode => {
                    if (itemNode.hasOwnProperty("children")) count += that.getTreeNodeChildrenCount(itemNode);
                    count++;
                });
                return count;
            }

            stateCount(step = 1) {
                let that = this;
                let countEl = that.stateCountEl;
                let count = countEl.html() | 0;
                countEl.html(count + step);
            }

            handleEventRequest(param) {
                let that = this;
                return new Promise((resolve, reject) => {
                    yunj.request({
                        url: that.args.handleUrl,
                        data: param,
                        type:"post",
                        loading:true
                    }).then(res => {
                        resolve(res.data);
                    }).catch(e => {
                        reject(e);
                    });
                });
            }

        }

        $(doc).ready(function () {
            new CategoryNormal();
        });
    });
</script>
{% endblock %}